package dao

import (
	"github.com/tianjigames/fairy/constants"
	"github.com/tianjigames/fairy/pojo"
	"github.com/tianjigames/fairy/template"
	"github.com/topfreegames/pitaya"
	"github.com/topfreegames/pitaya/logger"
	"sync"
)

var (
	PlayerDataDao *playerDataDao
	playerDataDaoOnce sync.Once
)

type playerDataDao struct {
	BaseDao
}

func NewPlayerDataDao() *playerDataDao {
	playerDataDaoOnce.Do(func() {
		PlayerDataDao = &playerDataDao{}
	})
	return PlayerDataDao
}

func (p *playerDataDao) DeletePlayer(accountData *pojo.AccountData,playerData *pojo.PlayerData) error {
	session := p.enginer.NewSession()
	defer session.Close()

	err := session.Begin()
	if err != nil {
		logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
		return err
	}
	isContain := accountData.CutPlayerGuid(playerData.Guid)
	if !isContain && accountData.AccountId != playerData.AccountId {
		logger.Log.Errorf("delete player not player's accountId=%d,playerGuid=%d",accountData.AccountId,playerData.Guid)
	}

	_,err = session.Update(accountData)
	if err != nil {
		logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
		session.Rollback()
		return err
	}

	playerData.Status = pojo.RoleStateDelete
	if playerData.Rolelevel < 20 {//真正的删除
		_,err = session.Delete(playerData)
		if err != nil {
			logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
			session.Rollback()
			return err
		}

		err = p.DeleteCache(playerData)
		if err != nil {
			logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
			session.Rollback()
			return err
		}
	}else{//软删除
		_,err = session.Update(playerData)
		if err != nil {
			logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
			session.Rollback()
			return err
		}

		//更新缓存
		err = p.UpdateCache(playerData)
		if err != nil {
			logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
			session.Rollback()
			return err
		}
	}

	mailBox,err := PlayerMailBoxDao.GetPlayerMailBoxByPlayerGuid(playerData.GetGuid())
	if err != nil {
		logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
		session.Rollback()
		return err
	}

	if mailBox != nil {
		_,err = session.Delete(mailBox)
		if err != nil {
			logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
			session.Rollback()
			return err
		}
	}

	err = session.Commit()
	if err != nil {
		logger.Log.Errorf("DeletePlayer failed,error:%s",err.Error())
		session.Rollback()
		return err
	}

	return nil
}

func (p *playerDataDao) CreatePlayer(accountData *pojo.AccountData,roleData *pojo.PlayerData) error {
	s := p.enginer.NewSession()
	defer s.Close()

	err := s.Begin()
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		return err
	}

	var guid int64
	guid,err = GuidGeneratorDao.GenGuid(int(constants.GuidTypePlayer))
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		return err
	}

	var playerMailBox *pojo.PlayerMailBox
	playerMailBox,err = PlayerMailBoxDao.GetPlayerMailBoxByPlayerGuid(guid)
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		return err
	}

	if playerMailBox != nil {
		logger.Log.Infof("CreatePlayer failed,error:playermailbox exist")
		return nil
	}

	roleData.Guid = guid
	roleData.AccountId = accountData.AccountId
	roleData.ChannelId = accountData.ChannelId
	roleData.AccountName = accountData.Username
	roleData.AppId = accountData.AppId
	roleData.Status = pojo.RoleStateUse
	p.onPlayerCreated(accountData,roleData)

	_,err = s.Insert(roleData)
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		s.Rollback()
		return err
	}

	err = accountData.AddPlayerGuid(roleData.Guid)
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		s.Rollback()
		return err
	}

	err = p.Update(accountData,"accountId=?",accountData.AccountId)
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		s.Rollback()
		return err
	}

	err = p.AddCache(roleData)
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		s.Rollback()
		return err
	}

	playerMailBox = &pojo.PlayerMailBox{
		PlayerGuid:              roleData.Guid,
	}

	_,err = s.Insert(playerMailBox)
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		s.Rollback()
		return err
	}

	err = s.Commit()
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,error:%s",err.Error())
		s.Rollback()
		return err
	}

	return nil
}

func (p *playerDataDao) onPlayerCreated(accountData *pojo.AccountData,roleData *pojo.PlayerData) {
	v := pitaya.GetTemplateById(template.ThreeYbDataKey,accountData.Username)
	if v != nil && accountData.IngotplayerId <= 0{
		yb := v.(*template.ThreeYbData)
		roleData.BindBankMoney = roleData.BindBankMoney + yb.Ingot1
		accountData.IngotplayerId = roleData.Guid
	}
}



